#include "PositionModeler.h"
#include <string>
#include <map>
#include "ResultMap.h"
#include "DocMatch.h"
#include <iostream>

using namespace std;
PositionModeler::PositionModeler()
{
}

PositionModeler::~PositionModeler()
{
}

map<uint, vector<string> > PositionModeler::getBestSites(vector<ResultMap>* allResults, vector<uint>* wordlist)
{
	//cout << "Entrei no Position Modeler" << endl;
	map<string, vector<DocMatch> > inter;
	for(int i=0;i<allResults->size();i++) // Para cada palavra
	{
		//cout << "Estou na palavra de indice: " << i << endl;
		map<string,DocMatch>::iterator it;
		for(it=allResults->at(i).result.begin();it!=allResults->at(i).result.end();it++)
		{
			//cout << "Estou no documento: " << it->first << endl;
			if(inter.find(it->first)!=inter.end()) // Ja existe esse documento no "inter" ???
			{
				//cout << "Ele ja existia" << endl;
				inter[it->first][i] = it->second;
			}
			else
			{
				//cout << "Estou criando dummys" << endl;
				vector<DocMatch> v;
				
				for(int k=0;k<wordlist->size();k++)
				{	
					//cout << "estou tentando dar push no Dummy: " << k << endl;
					DocMatch dummy;
					v.push_back(dummy);
				}
				//cout << "Tou tentando fazer o assign1"<< endl;
				v[i] = it->second;
				inter[it->first]=v;
				//cout << "Consegui fazer o assign"<< endl;
			}
			//cout << "Sai do documento: " << it->first << endl;
		}
	}
	/**
	 * Agora, as estruturas necessarias ja estao montadas =)
	 */
	map<uint, vector<string> > result;
	map<string, vector<DocMatch> >::iterator it;
	for(it=inter.begin();it!=inter.end();it++)
	{
		if(inter[it->first].size()==wordlist->size())
		{
			//cout << "Entrnando no Loop1 do Iterator Doc = " << it->first << endl;
			uint curMinDistance = 10000000;		
			for(int i=0;i< it->second[0].matches.size();i++) // Passando pela primeira palavra
			{
				//cout << "Entrnando na Primeira palavra" << endl;
				uint curDistance= 0;
				uint nextPos = 0;
				int curPos = it->second[0].matches[0];
				for(int j=1;j<it->second.size();j++)
				{
					//cout << "Tentando buscar mais proxima palavra num:" << j << endl;
					nextPos = PositionModeler::findClosest(&(it->second),j,curPos);
					curDistance += (nextPos - curPos);
					curPos = nextPos;
				}
				if(curDistance < curMinDistance)
					curMinDistance = curDistance;
			}
			if(result.find(curMinDistance) != result.end())
				result[curMinDistance].push_back(it->first);
			else
			{
				vector<string> v;
				v.push_back(it->first);
				result[curMinDistance]=v;
			}
			//cout << " Doc: " << result[it->first] << " MinDis: " << curMinDistance << endl;
		}
		else
		{
			if(result.find(10000000) != result.end())
							result[10000000].push_back(it->first);
						else
						{
							vector<string> v;
							v.push_back(it->first);
							result[10000000]=v;
						}
					//cout << " Doc: " << result[it->first] << " MinDis: " << curMinDistance << endl;
		}
		}

	return result;
}

uint PositionModeler::findClosest(vector<DocMatch>* inter, uint wordNumber, uint curPos)
{
	int i=0;
	for(;i< inter->at(wordNumber).matches.size();i++)
	{
		if(inter->at(wordNumber).matches.at(i) > curPos)
			return inter->at(wordNumber).matches.at(i);
	}
	return 50000000;
}
